<script lang="ts">
    import { onDestroy } from "svelte";
    import { useClassList } from "../utils/useClassList";
    import type { SplitProps } from "./Split";

    const props: SplitProps = $props();

    const dir = props.dir || "v";
    let wrap: HTMLElement;
    let prev: HTMLElement;
    const classList = $derived(
        useClassList(props, "cm-split-wrap", {
            [`cm-split-wrap-${props.dir || "v"}`]: true,
        })
    );

    let initSplit: any = props.split;
    if (initSplit && initSplit < 1) {
        initSplit = initSplit * 100 + "%";
    }
    let split = $state(initSplit || "50%");
    const store = $state({
        dragging: false,
        x: NaN,
        y: NaN,
        deltaX: 0,
        deltaY: 0,
    });
    const min = props.min || 40;

    const handlerClassList = $derived({
        "cm-split-handler": true,
        "cm-split-dragging": store.dragging,
        [`cm-split-handler-${props.dir || "v"}`]: true,
    });

    $effect(() => {
        const wrapRect = wrap.getBoundingClientRect();
        const wrapSize = dir === "v" ? wrapRect.width : wrapRect.height;
        let wh: number | string = dir === "v" ? prev.style.width : prev.style.height;
        if (wh.indexOf("px") > -1) {
            wh = (parseFloat(wh) / wrapSize) * 100;
        } else {
            wh = parseFloat(wh);
        }
        const max = props.max ? (props.max / wrapSize) * 100 : 100 - (min / wrapSize) * 100;
        wh = wh + ((dir === "v" ? store.deltaX : store.deltaY) / wrapSize) * 100;
        wh = Math.max(wh, (min / wrapSize) * 100);
        wh = Math.min(wh, max);
        split = wh + "%";
    });

    const prevStyle = $derived(`${dir === "v" ? "width" : "height"}: ${split}`);
    const handlerStyle = $derived(`${dir === "v" ? "left" : "top"}: ${split}`);
    const nextStyle = "flex: 1";

    const onDragStart = (e: any) => {
        if (typeof e.button === "number" && e.button !== 0) return false;

        store.dragging = true;
        const x = e.clientX;
        const y = e.clientY;
        store.x = x;
        store.y = y;

        document.addEventListener("mousemove", onDragMove, false);
        document.addEventListener("mouseup", onDragEnd, false);
    };

    const onDragMove = (e: any) => {
        const deltaX = e.clientX - store.x;
        const deltaY = e.clientY - store.y;
        store.x = e.clientX;
        store.y = e.clientY;
        store.deltaX = deltaX;
        store.deltaY = deltaY;
    };

    const onDragEnd = (e: any) => {
        store.dragging = false;
        document.removeEventListener("mousemove", onDragMove);
        document.removeEventListener("mouseup", onDragEnd);
        store.deltaX = 0;
        store.deltaY = 0;
    };

    onDestroy(() => {
        document.removeEventListener("mousemove", onDragMove);
        document.removeEventListener("mouseup", onDragEnd);
    });
</script>

<div class={classList} bind:this={wrap}>
    <div style={prevStyle} bind:this={prev} class={`cm-split-panel cm-split-${dir === "v" ? "left" : "top"}`}>
        {@render props.prev()}
    </div>
    <div class="cm-slpit-handler-wrap" style={handlerStyle}>
        <div class={handlerClassList} onmousedown={onDragStart} role="button" aria-label="Drag to resize" tabindex="0">
            <div class="cm-split-handler-bar-wrap">
                {#if props.customHandler}
                    {@render props.customHandler()}
                {:else}
                    {#each [1, 2, 3, 4, 5, 6, 7, 8] as item}
                        <div class="cm-split-handler-bar"></div>
                    {/each}
                {/if}
            </div>
        </div>
    </div>
    <div style={nextStyle} class={`cm-split-panel cm-split-${dir === "v" ? "right" : "bottom"}`}>
        {@render props.next()}
    </div>
</div>
